﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SIUSBXP_DLL;
using System.IO;
using System.Threading;
namespace Accelerometer_Controller
{
    public partial class Form1 : Form

    {

        IntPtr o = IntPtr.Zero;
        IntPtr hUSB = IntPtr.Zero;
        
       // Stream output;
        public Form1()
        {
            InitializeComponent();
        }
        private uint checkRX(IntPtr hUSB)
        {
            // System.Threading.Thread.Sleep(10);
            IntPtr o = IntPtr.Zero;
            byte[] readbuffer;
            uint bytesreturned = 0;
            uint numberBytesInQueue = 0;
            uint statusofQueue = 0;
            SIUSBXP.SI_CheckRXQueue(hUSB, ref numberBytesInQueue, ref statusofQueue);
            appendText("NumberOfBytesInQueue: " + numberBytesInQueue);
            appendText("Status of Queue: " + statusofQueue);
            
            if (numberBytesInQueue > 0)
            {
                readbuffer = new byte[numberBytesInQueue];
                int status = SIUSBXP.SI_Read(hUSB, readbuffer, numberBytesInQueue, ref bytesreturned, o);
                if (status == 0)
                {

                    appendText("BytesReturned: " + bytesreturned);
                    short x, y, z;
                        //  double c_x = 15.0344, c_y = 14.86356, c_z = 15.44872;
                        //  double real_x, real_y, real_z;
                    for (int i = 0; i < bytesreturned; i += 6)
                    {
                        if (bytesreturned - i >= 6)
                        {
                            try
                            {
                                x = (short)(readbuffer[i + 1] << 8 | readbuffer[i]);
                                y = (short)(readbuffer[i + 3] << 8 | readbuffer[i + 2]);
                                z = (short)(readbuffer[i + 5] << 8 | readbuffer[i + 4]);
                                //  real_x = (double)x * c_x;
                                // real_y = (double)y * c_y;
                                //real_z = (double)z * c_z + 63.25;
                                if (z > Convert.ToInt16(textBox3.Text))
                                {
                                    play = true;
                                }

                              //  appendRow(x, y, z);
                            }
                            catch { 
                            
                            }
                          
                        }
                    }
                }
                else appendText("status read error:" + status);
            }
            return numberBytesInQueue;
        }
        public void appendText(string value) {
            try
            {
                if (InvokeRequired)
                {
                    this.Invoke(new Action<string>(appendText), new object[] { value });
                    return;
                }
                richTextBox1.Text = value;
            }
            catch { }
        }
        public void appendstatus(string value)
        {
            try
            {
                if (InvokeRequired)
                {
                    this.Invoke(new Action<string>(appendstatus), new object[] { value });
                    return;
                }
                toolStripStatusLabel2.Text = "|  Status : " + value;
            }
            catch { }
        }
        public void appendRow(double val1, double val2,double val3)
        {
            try
            {
                if (InvokeRequired)
                {
                    this.Invoke(new Action<double, double, double>(appendRow), new object[] { val1, val2, val3 });
                    return;
                }
                dataGridView1.Rows.Add(val1, val2, val3);
            }
            catch { }
        }
       static string currentLoc = System.Windows.Forms.Application.StartupPath;
        string[] filePaths = Directory.GetFiles(currentLoc + "\\music", "*.mp3");
        void play_random() {
                
            
            if (!Media.Player.GetPlayer().IsPlaying()) 
            {
                Random rand = new Random();
                Media.Player.GetPlayer().Play(filePaths[rand.Next(filePaths.Length)]);
            }
        }
        void sendInitCommands() {
            //this all commands are from documentation of devices...
            //initialization, clean buffer, start getting XYZ, stop getting XYZ...
            byte[] writeBuf1 = { 0x00, 0x08, 0x07, 0x00 };
            uint numberOfbyteswritten = 0;
            IntPtr o = IntPtr.Zero;

            byte[] readbuffer = new byte[64];
            uint bytesreturned = 0;

            int statusUSB = 0;
            appendstatus("wait...");
           SIUSBXP.SI_FlushBuffers(hUSB,  1, 1).ToString();
            

            statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf1, (uint)writeBuf1.Length, ref numberOfbyteswritten, o);
            appendText("Number of bytes written: " + numberOfbyteswritten);

            byte[] writeBuf2 = { 0x28, 0x2E, 0x00 };
            statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf2, (uint)writeBuf2.Length, ref numberOfbyteswritten, o);
            appendText("Number of bytes written: " + numberOfbyteswritten);
       System.Threading.Thread.Sleep(50);
            byte[] writeBuf3 = { 0x29, 0x2E };
            statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf3, (uint)writeBuf3.Length, ref numberOfbyteswritten, o);
            appendText("Number of bytes written: " + numberOfbyteswritten);
       System.Threading.Thread.Sleep(50);
            checkRX(hUSB);
       
            byte[] writeBuf4 = { 0x28, 0x2C, f1 };
            statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf4, (uint)writeBuf4.Length, ref numberOfbyteswritten, o);
            appendText("Number of bytes written: " + numberOfbyteswritten);
       System.Threading.Thread.Sleep(50);
            
            byte[] writeBuf5 = { 0x29, 0x2C };
            statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf5, (uint)writeBuf5.Length, ref numberOfbyteswritten, o);
            appendText("Number of bytes written: " + numberOfbyteswritten);
       System.Threading.Thread.Sleep(50);
            ////////////////////////
       checkRX(hUSB);
            ///////////////////////////
             
                    byte[] writeBuf6 = { 0x28, 0x31, diap };
                    statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf6, (uint)writeBuf6.Length, ref numberOfbyteswritten, o);
                    appendText("Number of bytes written: " + numberOfbyteswritten);
        System.Threading.Thread.Sleep(50);
                    byte[] writeBuf7 = { 0x29, 0x31 };
                    statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf7, (uint)writeBuf7.Length, ref numberOfbyteswritten, o);
                    appendText("Number of bytes written: " + numberOfbyteswritten);
         System.Threading.Thread.Sleep(50);
                    ////////////////////////
                 checkRX(hUSB);
                    ///////////////////////////
                    
                byte[] writeBuf8 = { 0x28, 0x2F, 0x7F };
                   statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf8, (uint)writeBuf8.Length, ref numberOfbyteswritten, o);
                   appendText("Number of bytes written: " + numberOfbyteswritten);
         System.Threading.Thread.Sleep(50); 
                   byte[] writeBuf9 = { 0x29, 0x2F };
                   statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf9, (uint)writeBuf9.Length, ref numberOfbyteswritten, o);
                   appendText("Number of bytes written: " + numberOfbyteswritten);
        System.Threading.Thread.Sleep(50);
                   ////////////////////////
                checkRX(hUSB);
                   ///////////////////////////
                   byte[] writeBuf10 = { 0x28, 0x2E, 0x80 };
                   statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf10, (uint)writeBuf10.Length, ref numberOfbyteswritten, o);
                   appendText("Number of bytes written: " + numberOfbyteswritten);
        System.Threading.Thread.Sleep(50);
                   byte[] writeBuf11 = { 0x29, 0x2E };
                   statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf11, (uint)writeBuf11.Length, ref numberOfbyteswritten, o);
                   appendText("Number of bytes written: " + numberOfbyteswritten);
        System.Threading.Thread.Sleep(50);
                   ////////////////////////
               checkRX(hUSB);
                   ///////////////////////////
                     byte[] writeBuf12 = { 0x28, 0x2D, 0x08 };
                   statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf12, (uint)writeBuf12.Length, ref numberOfbyteswritten, o);
                   appendText("Number of bytes written: " + numberOfbyteswritten);
        System.Threading.Thread.Sleep(50);
                   byte[] writeBuf13 = { 0x29, 0x2D };
                   statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf13, (uint)writeBuf13.Length, ref numberOfbyteswritten, o);
                   appendText("Number of bytes written: " + numberOfbyteswritten);
        System.Threading.Thread.Sleep(50);
                   ////////////////////////
               checkRX(hUSB);
                   ///////////////////////////
            
                              byte[] writeBuf = { 0x2B, 0x07, number[0], number[1], number[2], 0x00, f2, diap, 0x02 };
           
                              //appendText("\n0x2B 0x07 "+number[0].ToString("X2")+" "+number[1].ToString("X2")+" "+number[2].ToString("X2"));
                              statusUSB = SIUSBXP.SI_Write(hUSB, writeBuf, (uint)writeBuf.Length, ref numberOfbyteswritten, o);
                              appendText("Number of bytes written: " + numberOfbyteswritten);
          
                              if (statusUSB == (int)SIUSBXP.SI_SUCCESS)
                              {
                                  appendText("Successfully written!");
                                   System.Threading.Thread.Sleep(50);
                                  ////////////////////////
                                  uint cnt = checkRX(hUSB);
                                  bool stop = false;
                                  bool recurse = false;
                                  appendstatus(" ready");
                                  while (cnt >= 0)
                                  {
                                      if (this.IsDisposed) break;
                                      if (cnt > 0) stop = true;

                                      System.Threading.Thread.Sleep(50); //1000

                                      cnt = checkRX(hUSB);

                                      if (stop && cnt == 0) {
                                          recurse = true;
                                          break;
                                      }
                                      
                                  }
                                  /////////////////////////
                                  appendText("Number of samples = "+dataGridView1.Rows.Count.ToString());
                                  if (recurse) { 
                                      sendInitCommands(); 
                                  }
                              }
                            
        }
        void listenADXL345() {
            byte[] name = new byte[64];
            byte name_length = 0;
            int statusUSB = 0;
            if (inf > 0) {
                SIUSBXP.SI_GetDeviceProductString(hUSB, name, ref name_length, true);
                string ns = System.Text.Encoding.ASCII.GetString(name);
                appendText("Name of device: " + ns);

                statusUSB = SIUSBXP.SI_SetBaudRate(hUSB, 460800); //460800
                if (statusUSB == 0)//SUCCESS
                {
                    appendText("Set up BaudRate");
                    statusUSB = SIUSBXP.SI_SetLineControl(hUSB, 0x810);//Convert.ToUInt16("0000100000000000", 2));
                    if (statusUSB == 0) appendText("Set Line Control");

                    uint ReadTimeout = 0, Writetimeout = 0;
                    SIUSBXP.SI_GetTimeouts(ref ReadTimeout, ref Writetimeout);

                    if (ReadTimeout > 10000 && Writetimeout > 10000)
                        SIUSBXP.SI_SetTimeouts(5000, 5000);
                  ///////////////////////////
                    sendInitCommands();
                 /////////////////////////////
                }
                else
                {
                    appendText("Error code: " + statusUSB);
                }
             }
        }
        byte f1 = 6;
        byte f2 = 9;
        byte diap = 0x00;
        byte[] number;
        Thread newTh;
        private void startbtn_Click(object sender, EventArgs e)
        {
            
            double f_ = Convert.ToDouble(comboBox1.Text)/6.25;
            byte fstep =(byte)Math.Log(f_, 2);
            f1 += fstep;
            f2 =(byte)(9 - fstep);

            
            switch (comboBox2.Text) {
                case "±2g": { diap = 0; break; }
                case "±4g": { diap = 1; break; }
                case "±8g": { diap = 2; break; }
                case "±16g": { diap = 3; break; }
            }
            number = BitConverter.GetBytes(Convert.ToInt32(textBox1.Text));
           // MessageBox.Show(number[0].ToString("X2") + ":" + number[1].ToString("X2") + ":" + number[2].ToString("X2"));
            ThreadStart threadDeleg = new ThreadStart(listenADXL345);
            newTh = new Thread(threadDeleg);
            newTh.Start();
          //  listenADXL345();
        
            
        }
        uint inf = 0;
        private void timer1_Tick(object sender, EventArgs e)
        {
            
            if (hUSB == IntPtr.Zero || (int)hUSB == -1)
            { 
                SIUSBXP.SI_Open(0, ref hUSB); 
            }

            SIUSBXP.SI_GetNumDevices(ref inf);
           
            if (inf == 0)
            { 
              SIUSBXP.SI_Close(hUSB);
              hUSB = IntPtr.Zero;
            }

            if ((int)hUSB != -1 && hUSB != IntPtr.Zero)
            {
                toolStripStatusLabel1.Text = "USB connection : On.";
                toolStripStatusLabel1.ForeColor = Color.Green;
            }
            else {
                toolStripStatusLabel1.Text = "USB connection : Off.";
                toolStripStatusLabel1.ForeColor = Color.Red;
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            this.Dispose();
            Application.Exit();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            play = true;
        }
        bool play = false;
        private void timer2_Tick(object sender, EventArgs e)
        {
            try
            {
                if (play)
                {
                    play_random();
                    play = false;
                }
            }
            catch { }
        }

     
    }
}
